package cn.wolfcode.luowowo.website.web.controller;

/**
 * Created by Administrator on 2020/1/9.
 */

import cn.wolfcode.luowowo.article.domain.FlightOrder;
import cn.wolfcode.luowowo.article.domain.Travel;
import cn.wolfcode.luowowo.article.query.MytravelQueryObject;
import cn.wolfcode.luowowo.article.service.IFlightOrderService;
import cn.wolfcode.luowowo.cache.service.IScenicStaticVOService;
import cn.wolfcode.luowowo.cache.service.IStrategyStatisVOService;
import cn.wolfcode.luowowo.cache.service.ITravelStatisVOService;
import cn.wolfcode.luowowo.cache.service.IVisitorStatisVOService;
import cn.wolfcode.luowowo.cache.util.RedisKeys;
import cn.wolfcode.luowowo.cache.vo.TravelStatisVO;
import cn.wolfcode.luowowo.comment.domain.ScenicComment;
import cn.wolfcode.luowowo.comment.service.IMyScenicCommentService;
import cn.wolfcode.luowowo.common.exception.LogicException;
import cn.wolfcode.luowowo.common.util.AjaxResult;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.home.service.IUserHomeService;
import cn.wolfcode.luowowo.home.vo.UserHomeVO;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import cn.wolfcode.luowowo.website.web.annotation.RequireLogin;
import cn.wolfcode.luowowo.website.web.annotation.UserParam;
import cn.wolfcode.luowowo.website.web.util.CookieUtil;
import cn.wolfcode.luowowo.website.web.util.UploadUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 我的空间控制器
 */
@Controller
@RequestMapping("/mine")
public class MineController {
    @Reference
    private IUserHomeService userHomeService;
    //引入操作Redis的服务
    @Reference
    private ITravelStatisVOService travelStatisVOService;
    //使用数据库查询用户对象
    @Reference
    private IUserInfoService userInfoService;
    //引入redis操作访客数据
    @Reference
    private IVisitorStatisVOService visitorStatisVOService;
    //引入mongoDB操作 我的点评
    @Reference
    private IMyScenicCommentService myScenicCommentService;

    //引入redis操作收藏数据
    @Reference
    private IStrategyStatisVOService strategyStatisVOService;
    @Reference
    private IScenicStaticVOService scenicStaticVOService;
    //引入操作redis中的用户信息操作
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Reference
    //引入操作机票订单
    private IFlightOrderService flightOrderService;


    @Value("${file.path}")
    private String filePath;
    /**
     * 我的空间首页
     * @return
     */
    @RequireLogin
    @RequestMapping("/home")
    public String home(Model model, @UserParam UserInfo userInfo){
        //传入用户  根据用户id
        //查询出用户相关信息  关注用户  粉丝 关联游记 关联游记数量 已删除游记
        UserHomeVO vo = userHomeService.listMyHome(userInfo);  //统计数据有问题  应该在redis中拿? 不然数据不同步  不如浏览游记后不会马上更新浏览量  因为增加浏览数是在redis中完成的
        vo.setUserInfo(userInfo);
        //获取游记阅读量

        //点评相关
        List<ScenicComment> scenic = myScenicCommentService.listMyScenicComment(userInfo.getId());
        //获取每个点评对应和回复数量和点赞数量
        List<ScenicComment> scenicComments = userHomeService.setReplayAndThumb(scenic);
        vo.setScenicComment(scenicComments);
        if(scenicComments!=null){
            vo.setCommentNum(scenicComments.size());
        }
        model.addAttribute("vo",vo);
        return "/mine/homepage";
    }
    @RequireLogin
    @RequestMapping("/mytravelnotes")
    public String mytravelnotes(Model model, @UserParam UserInfo userInfo, @ModelAttribute("qo") MytravelQueryObject qo){
        qo.setUserId(userInfo.getId());
        //获得用户id  根据用户id获取游记集合  这里有分页功能
        PageInfo<Travel> pageInfo = userHomeService.queryAllTravelByUserId(qo);
        //根据游记id集合  去redis中查找阅读量  得出总阅读量
        List<Travel> travels = pageInfo.getList();
        int replynum = 0;
        int viewnum = 0;
        TravelStatisVO travelStatisVO = new TravelStatisVO();
        for (Travel travel : travels) {
            //获取该游记的阅读量浏览量等数据
             travelStatisVO = travelStatisVOService.getTravelStatisVO(travel.getId());
            //回复量
            replynum+=travelStatisVO.getReplynum();
            //阅读量
            viewnum+=travelStatisVO.getViewnum();
        }
        travelStatisVO.setReplynum(replynum);
        travelStatisVO.setViewnum(viewnum);
        //共享所有游记的统计数据
        model.addAttribute("travelStatisVO",travelStatisVO);
        model.addAttribute("pageInfo",pageInfo);
        //获得此作者的游记数量  共享
        model.addAttribute("travelNum",pageInfo.getList().size());
        //用户信息共享到页面  问题:如果访问别人的窝  不能通过此方法直接共享
        model.addAttribute("userInfo",userInfo);
        //访客数量统计  进入自己的没有新增 但是要显示出来
        UserHomeVO vo = new UserHomeVO();
        vo.setUserInfo(userInfo);
        //取出在redis中的历史访问统计数据,共享到页面中  //id是该空间用户的id
        List<UserInfo> historyVisitors = visitorStatisVOService.getHistoryByUserId(userInfo.getId());
        Collections.reverse(historyVisitors);
        //历史浏览量
        int historyViewNum = visitorStatisVOService.getHistoryViewNum(userInfo.getId());
        //今日浏览量
        int todayViewNum = visitorStatisVOService.getTodayViewNum(userInfo.getId());
        vo.setHistoryUserInfo(historyVisitors);
        vo.setHistoryViewNum(historyViewNum);
        vo.setTodayViewNum(todayViewNum);
        vo.setPageInfo(pageInfo);
        model.addAttribute("vo",vo);
        return "/mine/mytravelnotes";
    }


    //我的收藏
    @RequestMapping("/myCollection")
    public String myCollection(Model model,@UserParam UserInfo userInfo){
        if(userInfo==null){
            throw  new LogicException("请先登录");
        }
        //我的收藏景点回显
        model.addAttribute("scenicCollections",scenicStaticVOService.getStrategyStatisVOByUserId(userInfo.getId()));
        //我的收藏攻略回显
        model.addAttribute("strategyCollections",strategyStatisVOService.getStrategyStatisVOByUserId(userInfo.getId()));
        //我的收藏游记回显
        model.addAttribute("travelCollections",travelStatisVOService.getTravelStatisVOByUserId(userInfo.getId()));
        return "mine/travelcollection";
    }


    /**
     *
     * @param model
     * @param id  这个空间作者的id
     * @param visitor  访客用户对象
     * @return
     */
    //进入别人的窝
    @RequestMapping("/otherHome")
    public String otherHome(Model model,Long id,@UserParam UserInfo visitor){
        //如果是访问对象就是本用户,那么直接跳转到我的窝
        if(visitor!=null&&id==visitor.getId()){
            return "/mine/home";
        }
        //根据id查询这个用户的信息,相关游记,关注的用户 粉丝数量等
        //查询用户信息
        UserInfo userInfo = userInfoService.get(id);
        //根据用户相关信息  查询关注用户  粉丝 关联游记 关联游记数量 已删除游记(难搞)
        UserHomeVO vo = userHomeService.listMyHome(userInfo);  //统计数据有问题  应该在redis中拿? 不然数据不同步  不如浏览游记后不会马上更新浏览量  因为增加浏览数是在redis中完成的
        vo.setUserInfo(userInfo);
        //点评相关
        List<ScenicComment> scenic = myScenicCommentService.listMyScenicComment(userInfo.getId());
        //获取每个点评对应和回复数量和点赞数量
        List<ScenicComment> scenicComments = userHomeService.setReplayAndThumb(scenic);
        vo.setScenicComment(scenicComments);
        if(scenicComments!=null){
            vo.setCommentNum(scenicComments.size());
        }
        //访客功能   有最客集合(最新8个)  访客数量   今日访客  用redis?
        //如果是未登陆访问者进入到此页面,将不会增加历史数据
        if(visitor==null){
            model.addAttribute("vo",vo);
            return "/mine/otherHomepage";
        }
        //新增访客进入redis 的hset的集合  存进历史访问用户对象集合  统计数量
        visitorStatisVOService.addVisitor(visitor,id);
        //取出在redis中的历史访问统计数据,共享到页面中  //id是该空间用户的id
        List<UserInfo> historyVisitors = visitorStatisVOService.getHistoryByUserId(id);
        //历史浏览量
        int historyViewNum = visitorStatisVOService.getHistoryViewNum(id);
        //今日浏览量
        int todayViewNum = visitorStatisVOService.getTodayViewNum(id);
        vo.setHistoryUserInfo(historyVisitors);
        vo.setHistoryViewNum(historyViewNum);
        vo.setTodayViewNum(todayViewNum);


        model.addAttribute("vo",vo);
        return "/mine/otherHomepage";
    }

    //进入别人的游记
    @RequestMapping("/otherTravelnotes")
    public String otherTravelnotes(Model model,Long id,@ModelAttribute("qo") MytravelQueryObject qo){
        //先根据用户id获得用户对象
        UserInfo userInfo = userInfoService.get(id);
        qo.setUserId(userInfo.getId());
        //获得用户id  根据用户id获取游记集合  这里有分页功能
        PageInfo<Travel> pageInfo = userHomeService.queryAllTravelByUserId(qo);
        //根据游记id集合  去redis中查找阅读量  得出总阅读量
        List<Travel> travels = pageInfo.getList();
        int replynum = 0;
        int viewnum = 0;
        TravelStatisVO travelStatisVO = new TravelStatisVO();
        for (Travel travel : travels) {
            //获取该游记的阅读量浏览量等数据
            travelStatisVO = travelStatisVOService.getTravelStatisVO(travel.getId());
            //回复量
            replynum+=travelStatisVO.getReplynum();
            //阅读量
            viewnum+=travelStatisVO.getViewnum();
        }
        travelStatisVO.setReplynum(replynum);
        travelStatisVO.setViewnum(viewnum);
        //共享所有游记的统计数据
        model.addAttribute("travelStatisVO",travelStatisVO);
        model.addAttribute("pageInfo",pageInfo);
        //获得此作者的游记数量  共享
        model.addAttribute("travelNum",pageInfo.getList().size());
        //用户信息共享到页面  问题:如果访问别人的窝  不能通过此方法直接共享
        model.addAttribute("userInfo",userInfo);
        //访客数量统计  进入自己的没有新增 但是要显示出来
        UserHomeVO vo = new UserHomeVO();
        vo.setUserInfo(userInfo);
        //取出在redis中的历史访问统计数据,共享到页面中  //id是该空间用户的id
        List<UserInfo> historyVisitors = visitorStatisVOService.getHistoryByUserId(userInfo.getId());
        //列表反序
        Collections.reverse(historyVisitors);
        //历史浏览量
        int historyViewNum = visitorStatisVOService.getHistoryViewNum(userInfo.getId());
        //今日浏览量
        int todayViewNum = visitorStatisVOService.getTodayViewNum(userInfo.getId());
        vo.setHistoryUserInfo(historyVisitors);
        vo.setHistoryViewNum(historyViewNum);
        vo.setTodayViewNum(todayViewNum);
        model.addAttribute("vo",vo);
        return "/mine/otherTravelnotes";
    }

    //我的点评页面
    @RequireLogin
    @RequestMapping("/MyReview")
    public String MyReview(Model model, @UserParam UserInfo userInfo, @ModelAttribute("qo") MytravelQueryObject qo){
        UserHomeVO vo = userHomeService.listMyHome(userInfo);
        vo.setUserInfo(userInfo);
        //点评相关
        List<ScenicComment> scenic = myScenicCommentService.listMyScenicComment(userInfo.getId());
        //获取每个点评对应和回复数量和点赞数量
        List<ScenicComment> scenicComments = userHomeService.setReplayAndThumb(scenic);
        vo.setScenicComment(scenicComments);
        //点赞总数
        int thumbupnumAll = 0;
        for (ScenicComment scenicComment : scenicComments) {
            thumbupnumAll += scenicComment.getThumbupnum();
        }
        model.addAttribute("thumbupnumAll",thumbupnumAll);
        if(scenicComments!=null){
            vo.setCommentNum(scenicComments.size());
        }
        model.addAttribute("vo",vo);

        return "/mine/review";
    }


    //他的点评页面
    @RequestMapping("/otherReview")
    public String otherReview(Model model, @UserParam UserInfo visitor, @ModelAttribute("qo") MytravelQueryObject qo){
        //如果是访问对象就是本用户,那么直接跳转到我的窝
        if(visitor!=null&&qo.getUserId()==visitor.getId()){
            return "/mine/home";
        }
        //先根据用户id获得用户对象
        UserInfo userInfo = userInfoService.get(qo.getUserId());
        UserHomeVO vo = userHomeService.listMyHome(userInfo);
        vo.setUserInfo(userInfo);
        //点评相关
        List<ScenicComment> scenic = myScenicCommentService.listMyScenicComment(userInfo.getId());
        //获取每个点评对应和回复数量和点赞数量
        List<ScenicComment> scenicComments = userHomeService.setReplayAndThumb(scenic);
        vo.setScenicComment(scenicComments);
        //点赞总数
        int thumbupnumAll = 0;
        for (ScenicComment scenicComment : scenicComments) {
            thumbupnumAll += scenicComment.getThumbupnum();
        }
        model.addAttribute("thumbupnumAll",thumbupnumAll);
        if(scenicComments!=null){
            vo.setCommentNum(scenicComments.size());
        }
        model.addAttribute("vo",vo);

        return "/mine/otherReview";
    }

    //设置页面
    @RequireLogin
    @RequestMapping("/setting")
    public String setting(Model model,@UserParam UserInfo userInfo,UserInfo updateUser, HttpServletRequest request, HttpServletResponse response){

        //更新最新的用户数据
        UserInfo updateUserInfo = this.updateUserInfo(userInfo.getId(), request, response);
        //显示用户的绑定手机部分
        StringBuilder stringBuilder = new StringBuilder();
        String phone = userInfo.getPhone();
        String prePhone = phone.substring(0, 3);
        String postPhone = phone.substring(7,11);
        stringBuilder.append(prePhone).append("****").append(postPhone);
        updateUserInfo.setPhone(stringBuilder.toString());
        //把信息共享回显
        model.addAttribute("userInfo",updateUserInfo);
        return "/mine/setting";
    }


    //保存用户设置
    @RequireLogin
    @RequestMapping("/saveUserSetting")
    public String saveUserSetting(Model model, @UserParam UserInfo userInfo , UserInfo updateUser, HttpServletRequest request, HttpServletResponse response){
        userInfoService.updateSettingUserInfo(updateUser);
        //把信息共享回显  注意是redis中的用户信息要更新
        String token = CookieUtil.getToken(request, response);
        UserInfo updatedUser = userInfoService.getByUserId(userInfo.getId());
        String value = JSON.toJSONString(updatedUser);
        stringRedisTemplate.opsForValue().set(RedisKeys.USER_LOGIN.join(token), value, RedisKeys.USER_LOGIN.getTime(), TimeUnit.SECONDS);
        //显示用户的绑定手机部分
        StringBuilder stringBuilder = new StringBuilder();
        String phone = updatedUser.getPhone();
        String prePhone = phone.substring(0, 3);
        String postPhone = phone.substring(7,11);
        stringBuilder.append(prePhone).append("****").append(postPhone);
        updatedUser.setPhone(stringBuilder.toString());
        model.addAttribute("userInfo",updatedUser);
        return "/mine/setting";
    }



    //用户头像上传
    @RequireLogin
    @RequestMapping("/updateImg")
    @ResponseBody
    public Object updateImg(MultipartFile files,@UserParam UserInfo userInfo,Model model,HttpServletRequest request, HttpServletResponse response){
        AjaxResult ajaxResult = new AjaxResult();
        String fileName = UploadUtil.upload(files, filePath);
        //把这个url存进数据库  因为是本地的图片 所以要在url前加斜杆/  用网络图片要删除这个代码
        StringBuilder stringBuilder = new StringBuilder();
        String beforeBysprit = stringBuilder.append("/").append(fileName).toString();
        userInfoService.updateHeadImgById(beforeBysprit,userInfo.getId());

        //把信息共享回显  注意是redis中的用户信息要更新
        String token = CookieUtil.getToken(request, response);
        UserInfo updatedUser = userInfoService.getByUserId(userInfo.getId());
        String value = JSON.toJSONString(updatedUser);
        stringRedisTemplate.opsForValue().set(RedisKeys.USER_LOGIN.join(token), value, RedisKeys.USER_LOGIN.getTime(), TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().get(RedisKeys.USER_LOGIN.join(token));
        model.addAttribute("userInfo",updatedUser);
        model.addAttribute("headImg",updatedUser.getHeadImgUrl());
        ajaxResult.setData(beforeBysprit);
        return ajaxResult;
    }



 /*   //coverImageUpload
    @RequestMapping("/coverImageUpload")
    public String coverImageUpload(){
        return "";
    }*/


    //用户手机号码修改证码发送
    @RequestMapping("/userPhoneVerity")
    @ResponseBody
    public Object userPhoneVerity(@UserParam UserInfo userInfo , String phone ,Long id){
        AjaxResult ajaxResult = new AjaxResult();
        //判断是不是同一个用户,不是同一个用户提示异常
        AssertUtil.hasLength(phone, "手机号不能为空");
        if(userInfo.getId()!=id){
            throw new LogicException("不是本用户不要瞎改!");
        }else{
            //判断这个手机用户有没有在注册用户中
            AssertUtil.checkPhone(phone);
            Boolean checkPhone = userInfoService.checkPhoneById(phone,id); //返回值为真 说明数据库中有手机用户  可以搞
            if(!checkPhone){
                ajaxResult.setMsg("不要瞎改别人的手机");
                ajaxResult.setSuccess(false);
                return ajaxResult;
            }
            String code  = userHomeService.sendVerity(phone);
            ajaxResult.setMsg(code);
        }
        return ajaxResult;
    }

    //用户手机号码修改验证码发送提交
    @RequestMapping("/userPhoneVeritySubmit")
    @ResponseBody
    public Object userPhoneVeritySubmit(@UserParam UserInfo userInfo , String phone , String verifyCode ,Long id){
        AjaxResult ajaxResult = new AjaxResult();
        //判断是不是同一个用户,不是同一个用户提示异常
        AssertUtil.hasLength(phone, "手机号不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");
        Boolean ret = false;
        if(userInfo.getId()!=id){
            throw new LogicException("不是本用户不要瞎改!");
        }else{
            //判断输入的验证码正确与否
            ret = userHomeService.checkVerityCode(phone,verifyCode);
        }
        if(ret){
            return AjaxResult.success();
        }
        ajaxResult.setMsg("验证码不正确");
        ajaxResult.setSuccess(false);
        return ajaxResult;
    }


    //新的手机的验证和修改  userNewPhoneVerity
    @RequestMapping("/userNewPhoneVerity")
    @ResponseBody
    public Object userNewPhoneVerity(@UserParam UserInfo userInfo , String newMobile ,Long id){
        AjaxResult ajaxResult = new AjaxResult();
        //判断是不是同一个用户,不是同一个用户提示异常
        AssertUtil.hasLength(newMobile, "手机号不能为空");
        if(userInfo.getId()!=id){
            throw new LogicException("不是本用户不要瞎改!");
        }else{
            //判断这个手机用户有没有在注册用户中
            AssertUtil.checkPhone(newMobile);
            Boolean checkPhone = userInfoService.checkPhoneById(newMobile, id); //返回值为真 说明数据库中有手机用户  可以搞
            if(checkPhone){
                ajaxResult.setMsg("该手机已存在");
                ajaxResult.setSuccess(false);
                return ajaxResult;
            }
            String codeMsg  = userHomeService.sendVerity(newMobile);
        /*    //修改用户的手机号码
            userInfoService.updatePhoneById(phone,id);*/
            ajaxResult.setMsg(codeMsg);
        }
        return ajaxResult;
    }

    //新手机修改提交  userNewPhoneSubmit
    @RequestMapping("/userNewPhoneSubmit")
    @ResponseBody
    public Object userNewPhoneSubmit(Model model ,@UserParam UserInfo userInfo , String newMobile , String code ,Long id,HttpServletRequest request, HttpServletResponse response){
        AjaxResult ajaxResult = new AjaxResult();
        //判断是不是同一个用户,不是同一个用户提示异常
        AssertUtil.hasLength(newMobile, "手机号不能为空");
        AssertUtil.hasLength(code, "验证码不能为空");
        Boolean ret = false;
        if(userInfo.getId()!=id){
            throw new LogicException("不是本用户不要瞎改!");
        }else{
            //判断输入的验证码正确与否
            ret = userHomeService.checkVerityCode(newMobile,code);
        }
        if(ret){
            userInfoService.updatePhoneById(newMobile,id);
            ajaxResult.setMsg("修改成功!");
            //实时更新用户的数据
            UserInfo updateUserInfo = this.updateUserInfo(userInfo.getId(), request, response);
            model.addAttribute("userInfo",updateUserInfo);
            return ajaxResult;
        }
        ajaxResult.setMsg("验证码不正确");
        ajaxResult.setSuccess(false);
        return ajaxResult;
    }

    //更新用户的信息的方法 是在redis中更新的
    protected UserInfo updateUserInfo(Long id ,HttpServletRequest request, HttpServletResponse response){
        //把信息共享回显  注意是redis中的用户信息要更新
        String token = CookieUtil.getToken(request, response);
        UserInfo updatedUser = userInfoService.getByUserId(id);
        String value = JSON.toJSONString(updatedUser);
        stringRedisTemplate.opsForValue().set(RedisKeys.USER_LOGIN.join(token), value, RedisKeys.USER_LOGIN.getTime(), TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().get(RedisKeys.USER_LOGIN.join(token));
        return updatedUser;
    }

    //我的订单
    @RequireLogin
    @RequestMapping("orderform")
    public String orderform(Model model,@UserParam UserInfo userInfo){
        List<FlightOrder> flightOrders = flightOrderService.listById(userInfo.getId());
        model.addAttribute("user",userInfo);
        model.addAttribute("list",flightOrders);
        return "/mine/orderform";
    }

}
